package otSpaces.client;

import java.io.IOException;
import java.net.PasswordAuthentication;
import java.nio.ByteBuffer;
import java.util.Properties;

import otSpaces.OtSpaceFunctions;

import com.sun.sgs.client.ClientChannel;
import com.sun.sgs.client.ClientChannelListener;
import com.sun.sgs.client.simple.SimpleClient;
import com.sun.sgs.client.simple.SimpleClientListener;

/**
 * The recomended way to make a topic client is to use this class to build your
 * SimpleClient, implemetning SimpleTopicClient.Listener insteam of
 * SimpleClientListener. You can access the {@link SimpleClient} youself to do
 * whatever you need to. If you have some other API that relies on
 * SimpleClientListener (and not ServerSession) then you can create the
 * {@link OtSpaceClient}s yourself.
 */
public class SimpleOtClient {

	/**
	 * You must implement this interface to use the SimpleTopicClient.
	 */
	public static interface Listener extends OtSpaceClient.Listener,
			SimpleClientListener {

		public void joinedTopicSpace(String topicSpaceName);
	}

	public final SimpleClient _simpleClient;

	public SimpleOtClient(final Listener listener) {

		_simpleClient = new SimpleClient(new SimpleClientListener() {

			@Override
			public void disconnected(boolean graceful, String reason) {
				listener.disconnected(graceful, reason);
			}

			@Override
			public PasswordAuthentication getPasswordAuthentication() {
				return listener.getPasswordAuthentication();
			}

			@Override
			public ClientChannelListener joinedChannel(ClientChannel channel) {
				if (OtSpaceFunctions.isOtTopicSpaceName(channel.getName())) {

					final OtSpaceClient clientSpace = new OtSpaceClient(channel);

					listener.joinedTopicSpace(clientSpace._topicSpaceName);

					return clientSpace.wrap(listener);
				} else {
					return listener.joinedChannel(channel);
				}
			}

			@Override
			public void loggedIn() {
				listener.loggedIn();
			}

			@Override
			public void loginFailed(String reason) {
				listener.loginFailed(reason);
			}

			@Override
			public void receivedMessage(ByteBuffer message) {
				listener.receivedMessage(message);
			}

			@Override
			public void reconnected() {
				listener.reconnected();
			}

			@Override
			public void reconnecting() {
				listener.reconnecting();
			}
		});
	}

	/**
	 * Just a convenience method to handle login from HOST:PORT strings
	 */
	public void login(String hostPort) throws IOException {

		final Properties properties = new Properties(System.getProperties());

		properties.setProperty(
				"port",
				hostPort.toString().substring(
						hostPort.toString().indexOf(':') + 1));
		properties.setProperty(
				"host",
				hostPort.toString().substring(0,
						hostPort.toString().indexOf(':')));

		_simpleClient.login(properties);
	}
}
